package com.elh.sharding.java.config;

import com.elh.sharding.java.algorithm.PreciseModuloShardingTableAlgorithm;
import com.elh.sharding.java.utils.DataSourceUtil;
import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author liulei
 **/
public class DataSourceConfig {

    @Bean
    public DataSource dataSource() throws SQLException {
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());// 分表
        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "ds_${id % 2}")); // 分库策略
        shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("id", new PreciseModuloShardingTableAlgorithm())); // 分表策略
        return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, getProperties());
    }

    /**
     * 分表配置
     *
     * @return
     */
    private static TableRuleConfiguration getOrderTableRuleConfiguration() {
        TableRuleConfiguration result = new TableRuleConfiguration("sys_user", "ds$->{0..1}.sys_user$->{0..1}");
        result.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "id", getProperties()));
        return result;
    }

    /**
     * 数据源配置
     *
     * @return
     */
    private static Map<String, DataSource> createDataSourceMap() {
        Map<String, DataSource> result = new HashMap<>();
        result.put("ds_0", DataSourceUtil.createDataSource("ds_0"));
        result.put("ds_1", DataSourceUtil.createDataSource("ds_1"));
        return result;
    }

    private static Properties getProperties() {
        Properties properties = new Properties();
        properties.setProperty("sql.show",Boolean.TRUE.toString());
        return properties;
    }

}
